package com.dkha.server.services.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dkha.common.enums.ApiUrlEnum;
import com.dkha.common.enums.ErrEnum;
import com.dkha.common.enums.YNEnums;
import com.dkha.common.exception.DkException;
import com.dkha.common.http.HttpUtil;
import com.dkha.common.modules.vo.ApiVO;
import com.dkha.common.modules.vo.camera.CameraInfoVO;
import com.dkha.common.page.PageParam;
import com.dkha.common.util.UtilValidate;
import com.dkha.common.util.excel.ImportExcel;
import com.dkha.server.mappers.FaceCameraDao;
import com.dkha.server.modules.entities.FaceCameraEntity;
import com.dkha.server.modules.entities.faceCamera.FaceCameraExcel;
import com.dkha.server.modules.entities.faceCamera.FaceCameraInfo;
import com.dkha.server.modules.entities.faceCamera.FaceCameraList;
import com.dkha.server.modules.entities.faceCamera.InsertFaceCamera;
import com.dkha.server.services.FaceCameraService;
import com.dkha.server.services.IControlBayonetMidService;
import com.dkha.server.system.modules.sys.dao.SysDictDataDao;
import com.dkha.server.system.modules.sys.dao.SysRegionDao;
import com.dkha.server.system.modules.sys.entity.SysDictDataEntity;
import com.dkha.server.system.modules.sys.entity.SysRegionEntity;
import com.dkha.server.system.modules.sys.enums.RegionTopEnum;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;

/**
 * 摄像头表
 *
 * @author Mark sunlightcs@gmail.com
 * @since 1.0.0 2019-12-08
 */
@Service
public class FaceCameraServiceImpl extends ServiceImpl<FaceCameraDao, FaceCameraEntity> implements FaceCameraService {

    @Resource
    private FaceCameraDao faceCameraDaol;

    @Resource
    private HttpUtil<ApiVO> httpUtil;

    @Resource
    private SysRegionDao sysRegionDao;
    @Resource
    private SysDictDataDao sysDictDataDao;
    @Value("${api.server.prefix}")
    private String link;

    @Override
    public Page<FaceCameraList> getPage(PageParam pageParam) {
        Page<FaceCameraList> page = new Page<>(pageParam.getPageNo(), pageParam.getPageSize());
        //设置模糊查询参数
        Map<String, String> paramsNote = pageParam.paramsToLike(pageParam.getNote(), "cameraName");
        //分页查询
        List<Long> cameraRegion = new ArrayList<>();
        //查询当前区域下的所有摄像头
        if (pageParam.getNote().get("cameraRegion") != null && !"".equals(pageParam.getNote().get("cameraRegion").trim())) {
            List<Map<String, Object>> region = sysRegionDao.getRegion1(Long.parseLong(pageParam.getNote().get("cameraRegion")));
            for (Map<String, Object> map : region) {
                recursionGetRegion(map);
            }
            for (Map<String, Object> map : region) {
                test(cameraRegion, map);
            }
            cameraRegion.add(Long.parseLong(pageParam.getNote().get("cameraRegion")));
        }
        List<FaceCameraList> faceCameraLists = faceCameraDaol.getList(page, paramsNote, cameraRegion);

        page.setRecords(faceCameraLists);
        return page;
    }

    @Override
    public List<FaceCameraEntity> getAll(String cameraName) {
        QueryWrapper queryWrapper = new QueryWrapper<FaceCameraEntity>();
        queryWrapper.eq("is_valid", YNEnums.YES.code);
        queryWrapper.like(UtilValidate.isNotEmpty(cameraName), "camera_name", cameraName);
        List<FaceCameraEntity> all = this.list(queryWrapper);
        return all;
    }

    /**
     * 获取当前区域下的所有子区域id
     *
     * @param cameraRegion
     * @param map
     */
    public void test(List<Long> cameraRegion, Map<String, Object> map) {
        if (map.get("children") != null) {
            List<Map<String, Object>> children = (List<Map<String, Object>>) map.get("children");
            for (Map<String, Object> map1 : children) {
                test(cameraRegion, map1);
            }
        }
        cameraRegion.add((Long) map.get("value"));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer insertCamera(InsertFaceCamera insertFaceCamera) {
//        System.out.println("校验空参数");
        if (insertFaceCamera == null) {
            throw new DkException("参数为空");
        }
        //校验经纬度是否重复
        System.out.println("校验经纬度");
        FaceCameraEntity faceCameraInfo = this.findByCoordinate(insertFaceCamera.getCameraLongitude(), insertFaceCamera.getCameraLatitude());
        if (UtilValidate.isNotEmpty(faceCameraInfo)) {
            throw new DkException("摄像头经纬度坐标重复");
        }
        System.out.println(insertFaceCamera.getCameraLongitude());
        System.out.println(insertFaceCamera.getCameraLatitude());
        // 摄像头名称,ip,rtsp地址重复性校验
        System.out.println("校验名称iprtsp地址");
        FaceCameraEntity nameEntity = baseMapper.selectOne(new QueryWrapper<FaceCameraEntity>().eq("camera_name", insertFaceCamera.getCameraName().trim()).eq("is_valid", YNEnums.YES.code));
        FaceCameraEntity ipEntity = baseMapper.selectOne(new QueryWrapper<FaceCameraEntity>().eq("ip", insertFaceCamera.getIp().trim()).eq("is_valid", YNEnums.YES.code));
        FaceCameraEntity rtspUrlEntity = baseMapper.selectOne(new QueryWrapper<FaceCameraEntity>().eq("rtsp_url", insertFaceCamera.getRtspUrl().trim()).eq("is_valid", YNEnums.YES.code));
        //版本码表关联
        SysDictDataEntity brand = sysDictDataDao.selectById(insertFaceCamera.getIdBrand());
        System.out.println( insertFaceCamera.getCameraName());
        System.out.println( insertFaceCamera.getIp());
        System.out.println( insertFaceCamera.getRtspUrl());

        if (UtilValidate.isEmpty(brand)) {
            throw new DkException("摄像头型号不能为空");
        }
        insertFaceCamera.setBrand(brand.getDictLabel());

        if (nameEntity != null) {
            throw new DkException("摄像头名称不能重复");
        }
        if (ipEntity != null) {
            throw new DkException("摄像头ip不能重复");
        }
        if (rtspUrlEntity != null) {
            throw new DkException("摄像头rtsp地址不能重复");
        }
        System.out.println("开始装填map");
        Map map = new HashMap();
        map.put("name", insertFaceCamera.getCameraName());
        map.put("url", insertFaceCamera.getRtspUrl());
//        ApiVO result = httpUtil.post(link + ApiUrlEnum.CAMERA.getUrl(), map, ApiVO.class);
//        if (result == null || !ErrEnum.OK.getCode().equals(result.getCode())) {
//            throw new DkException("新增摄像头失败");
//        }
//        System.out.println("创建faceCamera新实体");
        FaceCameraEntity faceCameraEntity = new FaceCameraEntity();
//        System.out.println("复制属性到新实体");
        BeanUtils.copyProperties(insertFaceCamera, faceCameraEntity);
        System.out.println("设置状态码");
        faceCameraEntity.setStatus(YNEnums.NO.code);
//        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(result.getData()));
//        faceCameraEntity.setIdFaceCamera(Long.parseLong(jsonObject.getString("carmeraId")));
//        System.out.println("准备获取设置id"+System.currentTimeMillis());
        faceCameraEntity.setIdFaceCamera(System.currentTimeMillis());
//        System.out.println("查看获取设置的id");
//        System.out.println(faceCameraEntity.getIdFaceCamera());

//        String[] regions = faceCameraEntity.getCameraRegionFirstlevel().split(",");
        System.out.println("获取区域"+insertFaceCamera.getCameraRegionFirstlevel());

        String[] regions = insertFaceCamera.getCameraRegionFirstlevel().split(",");
        faceCameraEntity.setCameraRegion(regions[regions.length - 1]);
        faceCameraEntity.setCameraRegionFirstlevelBackUp("");
        //翻译摄像头区域层级冗余字段
        for (String region : regions) {
            SysRegionEntity sysRegionEntity = sysRegionDao.getById(Long.parseLong(region));
            faceCameraEntity.setCameraRegionFirstlevelBackUp(faceCameraEntity.getCameraRegionFirstlevelBackUp() + sysRegionEntity.getName());
        }
//        //TODO 摄像头位置类型码值翻译
//        SysDictDataEntity sysDictDataEntity = sysDictDataDao.selectById(faceCameraEntity.getCameratLocationtypeId());
//        faceCameraEntity.setCameratLocationtypeIdBackUp(sysDictDataEntity.getDictLabel());

        return baseMapper.insert(faceCameraEntity);
    }

    @Override
    public FaceCameraInfo findById(long idCamera) {
        FaceCameraEntity faceCameraEntity = baseMapper.selectById(idCamera);
        FaceCameraInfo faceCameraInfo = new FaceCameraInfo();
        if(faceCameraEntity != null){
            BeanUtils.copyProperties(faceCameraEntity, faceCameraInfo);
        }
        return faceCameraInfo;

    }

    @Override
    public List<Map<String, Object>> getAllCameraByRegionId(long regionId) {

        List<Long> cameraRegion = new ArrayList<>();
        List<Map<String, Object>> region = sysRegionDao.getRegion1(regionId);
        for (Map<String, Object> map : region) {
            recursionGetRegion(map);
        }
        for (Map<String, Object> map : region) {
            test(cameraRegion, map);
        }
        cameraRegion.add(regionId);


        return baseMapper.getAllCameraByRegionId(cameraRegion);
    }

    @Override
    public List<Map<String, Object>> getCameraByRegionId(long regionId) {
        List<Map<String, Object>> result = baseMapper.getCameraByRegionId(regionId);
//        return ConvertUtils.sourceToTarget(baseMapper.selectList(new QueryWrapper<FaceCameraEntity>()
//                .eq("is_valid", YNEnums.YES.code)
//                .eq("camera_region", regionId)), FaceCameraInfo.class);
        return result;
    }

    @Override
    public List<Map<String, Object>> getRegionUnControlCamera(long regionId) {

        return baseMapper.getRegionUnControlCamera(regionId);
    }

    @Override
    public List<Map<String, Object>> getRegion(Long pid) {
        /**
         * 获取所有第一级摄像头区域
         */
        List<Map<String, Object>> region = sysRegionDao.getRegion1(pid);
        //遍历获取所有子级摄像头区域
        for (Map<String, Object> map : region) {
            recursionGetRegion(map);
        }
        return region;
    }

    @Override
    public List<Map<String, Object>> getBayonet(Long pid) {
        List<Map<String, Object>> result = new LinkedList<>();

        //获取当前id下的区域
        List<Map<String, Object>> region = sysRegionDao.getRegion(pid);
        //获取当期区域下的所有有布控任务的摄像头
        List<Map<String, Object>> camera = baseMapper.findByRegion(String.valueOf(pid));
        result.addAll(region);
        result.addAll(camera);
        List<Map<String, Object>> copyRegion = new ArrayList<>();
        copyRegion.addAll(region);
        for (int i = 0; i < copyRegion.size(); i++) {
            int count = baseMapper.isCameraInRegion("%" + (Long) copyRegion.get(i).get("id") + "%");
            if (count < 1) {
                region.remove(copyRegion.get(i));
                continue;
            }
            if (copyRegion.get(i).get("type") != null && ((String) copyRegion.get(i).get("type")).endsWith("region")) {
                region.get(region.indexOf(copyRegion.get(i))).put("label", region.get(region.indexOf(copyRegion.get(i))).get("label") + "(区域)");
            }
            recursionGetBayonet(region.get(i));
        }
        for (Map<String, Object> map : camera) {
            if (map.get("type") != null && ((String) map.get("type")).endsWith("camera")) {
                map.put("label", map.get("label") + "(摄像头)");
            }
        }

        return result;
    }

    /**
     * 递归获取所有摄像头区域
     *
     * @param resoure
     */
    public void recursionGetRegion(Map<String, Object> resoure) {
        long id = resoure.get("value") == null ? RegionTopEnum.FATHER.value() : (Long) resoure.get("value");

        List<Map<String, Object>> region = sysRegionDao.getRegion1(id);
        if (region != null && region.size() != 0) {
            for (Map<String, Object> map : region) {
                recursionGetRegion(map);
            }
            resoure.put("children", region);
        }
    }

    /**
     * 递归 获取摄像头区域
     *
     * @param resoure
     */
    public void recursionGetBayonet(Map<String, Object> resoure) {
        long id = resoure.get("id") == null ? RegionTopEnum.FATHER.value() : (Long) resoure.get("id");

        List<Map<String, Object>> result = new LinkedList<>();
        List<Map<String, Object>> region = sysRegionDao.getRegion(id);
        List<Map<String, Object>> copyRegion = new ArrayList<>();
        copyRegion.addAll(region);
        List<Map<String, Object>> camera = baseMapper.findByRegion(String.valueOf(id));
        if (region != null && region.size() != 0) {

            for (int i = 0; i < copyRegion.size(); i++) {
                int count = baseMapper.isCameraInRegion("%" + (Long) copyRegion.get(i).get("id") + "%");
                if (count < 1) {
                    region.remove(copyRegion.get(i));
                    continue;
                }
                if (copyRegion.get(i).get("type") != null && ((String) copyRegion.get(i).get("type")).endsWith("region")) {
                    region.get(region.indexOf(copyRegion.get(i))).put("label", region.get(region.indexOf(copyRegion.get(i))).get("label") + "(区域)");
                }
                recursionGetBayonet(copyRegion.get(i));
            }
        }
        for (Map<String, Object> map : camera) {
            if (map.get("type") != null && ((String) map.get("type")).endsWith("camera")) {
                map.put("label", map.get("label") + "(摄像头)");
            }
        }
        result.addAll(region);
        result.addAll(camera);
        resoure.put("children", result);

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer update(FaceCameraInfo faceCameraInfo) {
        FaceCameraEntity faceCameraEntity = baseMapper.selectById(faceCameraInfo.getIdFaceCamera());
        if (faceCameraEntity == null) {
            throw new DkException("无此摄像头");
        }
        FaceCameraEntity old = this.findByCoordinate(faceCameraInfo.getCameraLongitude(), faceCameraInfo.getCameraLatitude());
        if (UtilValidate.isNotEmpty(old) && !faceCameraEntity.getIdFaceCamera().equals(old.getIdFaceCamera())) {
            throw new DkException("摄像头经纬度坐标重复");
        }
        FaceCameraEntity nameEntity = baseMapper.selectOne(new QueryWrapper<FaceCameraEntity>().eq("camera_name", faceCameraInfo.getCameraName().trim()).eq("is_valid", YNEnums.YES.code));
        FaceCameraEntity ipEntity = baseMapper.selectOne(new QueryWrapper<FaceCameraEntity>().eq("ip", faceCameraInfo.getIp().trim()).eq("is_valid", YNEnums.YES.code));
        FaceCameraEntity rtspUrlEntity = baseMapper.selectOne(new QueryWrapper<FaceCameraEntity>().eq("rtsp_url", faceCameraInfo.getRtspUrl().trim()).eq("is_valid", YNEnums.YES.code));
        //摄像头名称,ip,rtsp地址重复性校验
        if (nameEntity != null && !nameEntity.getIdFaceCamera().equals(faceCameraInfo.getIdFaceCamera())) {
            throw new DkException("摄像头名称不能重复");
        }
        if (ipEntity != null && !ipEntity.getIdFaceCamera().equals(faceCameraInfo.getIdFaceCamera())) {
            throw new DkException("摄像头ip不能重复");
        }
        if (rtspUrlEntity != null && !rtspUrlEntity.getIdFaceCamera().equals(faceCameraInfo.getIdFaceCamera())) {
            throw new DkException("摄像头rtsp地址不能重复");
        }
        //版本码表关联
        SysDictDataEntity brand = sysDictDataDao.selectById(faceCameraInfo.getIdBrand());
        if (UtilValidate.isNotEmpty(brand)) {
            faceCameraEntity.setIdBrand(brand.getDictTypeId().toString());
            faceCameraEntity.setBrand(brand.getDictLabel());
        } else {
            throw new DkException("摄像头品牌不能为空");
        }
        Map map = new HashMap(0);
        //判断是否修改了名称，rtsp
//        if (!faceCameraEntity.getCameraName().equals(faceCameraInfo.getCameraName()) ||
//                !faceCameraEntity.getRtspUrl().equals(faceCameraInfo.getRtspUrl())) {
//            map.put("name", faceCameraInfo.getCameraName());
//            map.put("url", faceCameraInfo.getRtspUrl());
//            map.put("carmeraId", faceCameraInfo.getIdFaceCamera());
//            ApiVO result = httpUtil.put(link + ApiUrlEnum.CAMERA.getUrl(), map, ApiVO.class);
//            if (result == null || !ErrEnum.OK.getCode().equals(result.getCode())) {
//                throw new DkException("修改摄像头失败");
//            }
//        }
        BeanUtils.copyProperties(faceCameraInfo, faceCameraEntity);
        //摄像头区域类型修改
        faceCameraEntity.setCameraRegionFirstlevel(null);
        faceCameraEntity.setCameraRegionFirstlevelBackUp("");
        String[] regionFirstlevelArrays = faceCameraInfo.getCameraRegionFirstlevelArrays();
        faceCameraEntity.setCameraRegion(String.valueOf(regionFirstlevelArrays[regionFirstlevelArrays.length - 1]));
        for (String regionId : regionFirstlevelArrays) {
            SysRegionEntity sysRegionEntity = sysRegionDao.getById(Long.parseLong(regionId));
            faceCameraEntity.setCameraRegionFirstlevelBackUp(faceCameraEntity.getCameraRegionFirstlevelBackUp() + sysRegionEntity.getName());
        }
        faceCameraEntity.setCameraRegionFirstlevel(StringUtils.join(regionFirstlevelArrays, ','));
//        //摄像头位置类型修改
//        SysDictDataEntity sysDictDataEntity = sysDictDataDao.selectById(faceCameraInfo.getCameratLocationtypeId());
//        faceCameraEntity.setCameratLocationtypeIdBackUp(sysDictDataEntity.getDictLabel());
        //TODO 摄像头位置类型码值翻译

        return baseMapper.updateById(faceCameraEntity);
    }

    @Autowired
    private IControlBayonetMidService iControlBayonetMidService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<FaceCameraEntity> findCameraByTask() {
        return iControlBayonetMidService.selectFaceCameraBytask();
    }


    @Transactional
    @Override
    public Integer delete(long camera) {
        FaceCameraEntity entity = baseMapper.selectById(camera);
        if (entity == null) {
            throw new DkException("无此摄像头");
        }

        //验证摄像头是否已经布控了任务

        Long res = iControlBayonetMidService.selectexistByCarmeID(String.valueOf(camera));
        if (res.intValue() > 0) {
            throw new DkException("删除摄像头失败，当前摄像头存在布控任务");
        }


//        ApiVO result = httpUtil.delete(link + ApiUrlEnum.CAMERA.getUrl() + "/" + camera, ApiVO.class);
//        if (result == null || !ErrEnum.OK.getCode().equals(result.getCode())) {
//            throw new DkException("删除摄像头失败");
//        }
        entity.setIsValid(YNEnums.NO.code);
        return baseMapper.updateById(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer status(long camera, boolean status) {
        FaceCameraEntity entity = baseMapper.selectById(camera);
        if (status) {
            entity.setStatus(YNEnums.YES.code);
        } else {
            entity.setStatus(YNEnums.NO.code);
        }
        return baseMapper.updateById(entity);
    }

    @Override
    public List<FaceCameraExcel> importExcel(MultipartFile multipartFile) {
        List<FaceCameraExcel> errorList = new ArrayList<>(0);
        try {
            ImportExcel ei = new ImportExcel(multipartFile, 1, 0);
            List<FaceCameraExcel> cameraExcels = ei.getDataList(FaceCameraExcel.class);

            for (FaceCameraExcel faceCameraExcel : cameraExcels) {
                //TODO 数据校验空
                if (checkNull(errorList, faceCameraExcel)) {
                    continue;
                }
                //码表关联查询

            }
        } catch (InvalidFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return errorList;
    }

    private boolean checkNull(List<FaceCameraExcel> error, FaceCameraExcel faceCameraExcel) {
        //空值校验
        if (UtilValidate.isEmpty(faceCameraExcel.getIp())) {
            faceCameraExcel.setMessage("ip地址不能为空");
            error.add(faceCameraExcel);
            return true;
        }

        return false;
    }

    @Override
    public FaceCameraEntity findByCoordinate(String cameraLongitude, String cameraLatitude) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(FaceCameraEntity.CAMERA_LONGITUDE, cameraLongitude);
        queryWrapper.eq(FaceCameraEntity.CAMERA_LATITUDE, cameraLatitude);
        FaceCameraEntity faceCameraEntity = baseMapper.selectOne(queryWrapper);
        return faceCameraEntity;
    }

    @Override
    public CameraInfoVO selectFaceCameraID(String idFaceCamera) {
        return baseMapper.selectFaceCameraID(idFaceCamera);
    }
}
